package com.dake.jdk8.conllection.list;

import com.dake.jdk8.vo.User;

import java.util.*;
import java.util.stream.Collectors;

public class List_001 {

    public static void main(String[] args) {
        List<User> users = Arrays.asList(new User(1, "zhangsan", 38, 172.5),
                new User(2, "lisi", 38, 180),
                new User(3, "wangwu", 25, 185),
                new User(4, "maliu", 25, 180),
                new User(5, "zhouwu", 30, 170));

        System.out.println("------------------filter操作-----------------------------------------");
        // 筛选出年龄大于18岁的人
        List<User> ageBigThan18 = users.stream().filter(user -> user.getAge() > 18).collect(Collectors.toList());
        ageBigThan18.forEach(System.out::println);
        System.out.println("------------------111111111-----------------------------------------");

        // 筛选出年龄大于18且身高高于170的人
        users.stream().filter(user -> user.getAge() > 18).filter(user -> user.getHeight() > 170).forEach(System.out::println);
        System.out.println("-----------------------22222222------------------------------------");

        // 筛选出年龄等于18且身高大于180的人
        users.stream().filter(user -> user.getAge() == 18).filter(user -> user.getHeight() > 180).forEach(System.out::println);
        System.out.println("-----------------------3333333333------------------------------------");

        // 筛选出年龄等于18且身高大于180的人
        users.stream().filter(user -> user.getAge() < 18).filter(user -> user.getHeight() > 180).forEach(System.out::println);

        System.out.println("------------------sorted操作-----------------------------------------");
//        Collections.sort(users);
//        users.stream().sorted()
        // 该方法会改变原集合的排序书序，且无返回值——因为已改变原集合的排序顺序
//        users.sort(Comparator.comparingInt(User::getAge));
        users.forEach(System.out::println);
        System.out.println("-----------------------44444444444444------------------------------------");
        // 按照身高逆序排序
        users.stream().sorted(Comparator.comparingDouble(User::getHeight).reversed()).collect(Collectors.toList())
                .forEach(System.out::println);
        System.out.println("-----------------------555555555555------------------------------------");
        // 先按年龄排序，然后按照身高排序
        users.stream().sorted(Comparator.comparingInt(User::getAge).thenComparingDouble(User::getHeight))
                .collect(Collectors.toList()).forEach(System.out::println);

        System.out.println("-----------------------map操作------------------------------------");
        // 取最大值、最小值等操作：max,min,sum
        int age = users.stream().mapToInt(User::getAge).max().getAsInt();
        User user1 = users.stream().max(Comparator.comparingInt(User::getAge)).get();
        System.out.println(user1);
        System.out.println("-----------------------6666666666------------------------------------");
        // 找到年龄大于25岁的所有人的名字，并将所有人按照年龄排序
        users.stream().filter(user -> user.getAge() > 25).sorted(Comparator.comparingInt(User::getAge))
                .map(User::getName).collect(Collectors.toList()).forEach(System.out::println);
        System.out.println("-----------------------77777777777------------------------------------");
        // 找到年龄大于25岁的所有人的身高，并将所有人分别按照身高、年龄排序
        // 此时只能先排序然后在使用map拿到对应的人的身高，不然先拿到人的身高的集合再去排序，此时集合只有身高，变不能进行排序
        users.stream().filter(user -> user.getAge() > 25).sorted(Comparator.comparingInt(User::getAge)
                .thenComparingDouble(User::getHeight)).map(User::getHeight).collect(Collectors.toList())
                .forEach(System.out::println);
        System.out.println("-----------------------8888888888------------------------------------");
        users.stream().limit(2).collect(Collectors.toList()).forEach(System.out::println);
        System.out.println("-----------------------999999999------------------------------------");
        users.stream().skip(2).collect(Collectors.toList()).forEach(System.out::println);
        // 还有distinct操作，这里不方便演示
        System.out.println("-----------------------101010101010------------------------------------");
        users.stream().map(User::getAge).forEach(System.out::println);
        System.out.println("-----------------------111111111111111------------------------------------");
        users.stream().map(User::getName).map(String::toUpperCase).forEach(System.out::println);

        System.out.println("-----------------------查找和匹配allMatch、 anyMatch、 noneMatch、 findFirst和findAny------------------------------------");
        // //判断集合中是否有任何符合条件的元素 终端操作返回boolean
        boolean b = users.stream().anyMatch(user -> user.getAge() > 100);
        System.out.println(b);
        System.out.println(users.stream().allMatch(user -> user.getAge() > 20));
        System.out.println(users.stream().noneMatch(user -> user.getAge() > 100));
        //你可能会想，为什么会同时有findFirst和findAny呢？答案是并行。找到第一个元素
        // 在并行上限制更多。如果你不关心返回的元素是哪个，请使用findAny，因为它在使用并行流
        //  时限制较少。
        System.out.println(users.stream().filter(user -> user.getAge() > 25).findAny());
        System.out.println(users.stream().filter(user -> user.getAge() > 25).findFirst());

        System.out.println("------------规约reduce----------------");
        /*
            规约的使用规则：从第一个参数开始参加计算
         */
        List<Integer> integers = Arrays.asList(2, 0, 4, 5, 3, 1);
        // 0+2+1+4+8+7+10
        Integer reduce = integers.stream().reduce(0, Integer::sum);
        System.out.println(reduce);
        System.out.println(integers.stream().reduce(-10, Integer::sum));
        System.out.println(integers.stream().reduce(11, Integer::compareTo));
        // 求最大值最小值
        System.out.println(integers.stream().reduce(Integer::max));
        System.out.println(integers.stream().reduce(Integer::min));
        System.out.println(integers.stream().reduce((a, b1) -> a < b1 ?a : b1));

        // 对基本数据类型进行装箱boxed
        integers.stream().mapToInt(i -> i * 2).boxed().collect(Collectors.toList()).forEach(System.out::println);


        // 求users中身高的个数
        System.out.println(users.stream().map(h -> 1).reduce(Integer::sum));
        // 对所有的人员的id求和
        System.out.println(users.parallelStream().map(User::getId).reduce(0, Integer::sum));

        System.out.println("--------------------groupBy按照某个属性进行分组----------------");
        // 按照年龄分组
        System.out.println(users.stream().collect(Collectors.groupingBy(User::getAge)));
        // 按照年龄分组，求该组中的平均身高
        Map<Integer, Double> collect = users.stream().collect(Collectors.groupingBy(User::getAge,
                Collectors.averagingDouble(User::getHeight)));
        collect.forEach((k, v) -> System.out.println("key:" + k + ", value:" + v));
        System.out.println("-------------------------------------1212152121212------------------------------");
        // 按照年龄分组，求该组中人员的id之和
        Map<Integer, Integer> collect1 = users.stream().collect(Collectors.groupingBy(User::getAge,
                Collectors.summingInt(User::getId)));
        collect1.forEach((k, v) -> System.out.println("key:" + k + ", value:" + v));
        System.out.println("-------------------------------------131313131313131------------------------------");
        // 按照 年龄分组，求该组中的数据个数
        Map<Integer, Long> collect2 = users.stream().collect(Collectors.groupingBy(User::getAge,
                Collectors.counting()));
        collect2.forEach((k, v) -> System.out.println("key:" + k + ", value:" + v));

        List<Integer> list = new ArrayList<>();
        list.add(1);
        Optional.of(list).map(l -> l.get(0)).orElse(1);
        Optional.of(list).isPresent();

    }
}
